home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / disk utilities / backup / backup_restore / backup_src_v3.20.lha / Protocol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-28  |  12.9 KB  |  532 lines

  1. /* Protocol.c */
  2. /* 27 Jan 1996 21:56:12 */
  3.  
  4. #ifndef    BACKUP_INCLUDE
  5. #include "IncludeAll.c"
  6. #endif
  7. #include "Backup.h"
  8. #include "Backup_proto.h"
  9. #include "BackupStrings.h"
  10.  
  11.  
  12. #define    PROTBUFF_SIZE    (65536)        /* Buffergröße für Protokollfile */
  13.  
  14.  
  15. static void TranslateProtFileName(char *ProtFileName, size_t MaxLength);
  16. static short WriteBinProt(struct NameField *file, FILE *fd);
  17. static BOOL CompressProtFile(const char *ProtFileName);
  18. static void WriteCompressedProt(struct NameField **nf, char *Bytes, size_t Length);
  19.  
  20.  
  21. /* aus CmdFile.c */
  22. extern FILE *aktCmdFile;        /* fp für Kommandofile */
  23. extern char __far CmdFileName[];    /* Name des Kommandofile */
  24.  
  25.  
  26. /* aus Backup.c */
  27. extern BPTR aktReadFileHandle;        /* fh für Lese-File */
  28. extern struct BackupOptions myOptions;
  29. extern unsigned char disknr;        /* laufende Nummer der Backup-Diskette */
  30. extern struct NextFileInfo NFInfo;    /* Datensatz für NextFile() */
  31. extern char StartZeit[8];
  32. extern struct Window *aktWindow;
  33.  
  34.  
  35. FILE *ProtFileHandle = NULL;        /* File Handle für Protokoll-File */
  36. BOOL ProtFileValid;            // Flag: Protfile enthält sinnvolle Daten (wird am Ende von NamenSchreiben gesetzt)
  37.  
  38. static char __far NormalizedProtFileName[FMSIZE];
  39. static unsigned long ProtNfCount;    /* kumulierte Anzahl Directory-Einträge (gesamtes Backup) */
  40. static unsigned long ProtNfLength;    /* kumulierte Länge der Directory-Einträge (gesamtes Backup) */
  41. static fpos_t InfoPos;            /* File-Position für :INFO - Zeile */
  42. static BPTR CompressedProtFileHandle;    /* File Handle für komprimierte ProtFiles */
  43.  
  44.  
  45. void OpenProtFile(void)
  46. {
  47.     char zeile[129];
  48.     short error = 0;
  49.     BPTR ProtFileLock;
  50.  
  51.     TranslateProtFileName(myOptions.bo_ProtFileName, sizeof(myOptions.bo_ProtFileName));
  52.  
  53.     ProtNfCount = 0l;
  54.     ProtNfLength = 0l;
  55.     InfoPos = 0l;
  56.  
  57.     ProtFileValid = FALSE;
  58.  
  59.     /* ProtFile neu anlegen */
  60.     ProtFileHandle = fopen(myOptions.bo_ProtFileName, "w");
  61.     if (ProtFileHandle)
  62.         fclose(ProtFileHandle);
  63.  
  64.     ProtFileLock = Lock(myOptions.bo_ProtFileName, ACCESS_READ);
  65.     if (ProtFileLock)
  66.         {
  67.         NameFromLock(ProtFileLock, NormalizedProtFileName,
  68.             sizeof(NormalizedProtFileName));
  69.         UnLock(ProtFileLock);
  70.         }
  71.  
  72.     if (NULL == strchr(myOptions.bo_ProtFileName, ':') && *NormalizedProtFileName)
  73.         {
  74.         /* der angebene Filename ist relativ. Er wird jetzt umgesetzt
  75.            in einen absoluten Pfadnamen (mit Device) */
  76.         stccpy(myOptions.bo_ProtFileName, NormalizedProtFileName,
  77.             sizeof(myOptions.bo_ProtFileName));
  78.         }
  79.  
  80.     ProtFileHandle = fopen(myOptions.bo_ProtFileName, "w");
  81.     if (NULL == ProtFileHandle)
  82.         {
  83.         /* Fehler beim Protokollfile anlegen */
  84.         alarm(GetString(MSG_CANNOT_CREATE_PROT), myOptions.bo_ProtFileName, GetIoErrText());
  85.         }
  86.     else if (PT_Binary == myOptions.bo_ProtFile)
  87.         {
  88.         /* Protokoll im Binärformat */
  89.         setvbuf(ProtFileHandle, NULL, _IOFBF, PROTBUFF_SIZE);
  90.  
  91.         error = fwrite(PROTFILEHEADER, sizeof(PROTFILEHEADER), 1, ProtFileHandle) != 1;
  92.         }
  93.     else
  94.         {
  95.         /* Protokoll als Klartext */
  96.         setvbuf(ProtFileHandle, NULL, _IOFBF, PROTBUFF_SIZE);
  97.  
  98.         if (aktCmdFile)
  99.             error = fprintf(ProtFileHandle, GetString(MSG_BACKUP_WITH_CMDFILE_PROT),
  100.                 NurName(CmdFileName)) <= 0;
  101.         else
  102.             {
  103.             char c;
  104.  
  105.             strcpy(zeile, IsListEmpty((struct List *) &NFInfo.nfi_FirstDir) ?
  106.                 GetString(MSG_LIST) :
  107.                 ShortFileName(((struct DirEntry *) NFInfo.nfi_FirstDir.mlh_Head)->Name, 40) );
  108.  
  109.             c = zeile[strlen(zeile)-1];
  110.             if ( c != ':' && c != '/' )
  111.                 strcat(zeile, "/");
  112.  
  113.             error = fprintf(ProtFileHandle, GetString(MSG_BACKUP_OF_PROT), zeile) <= 0;
  114.  
  115.             if (!error)
  116.                 error = fprintf(ProtFileHandle, GetString(MSG_INCLUDED_FILES_PROT),
  117.                     myOptions.bo_IncludeFile.RawName) <= 0;
  118.  
  119.             if (!error && *myOptions.bo_ExcludeFile.RawName)
  120.                 error = fprintf(ProtFileHandle, GetString(MSG_EXCLUDED_FILES_PROT),
  121.                     myOptions.bo_ExcludeFile.RawName) <= 0;
  122.  
  123.             if (!error && myOptions.bo_UseFirstDate)
  124.                 {
  125.                 struct myDate datevon;
  126.  
  127.                 UnpackDate(myOptions.bo_FirstDate, &datevon);
  128.                 error = fprintf(ProtFileHandle, GetString(MSG_ONLYFILESFROM_PROT),
  129.                     datevon.Day, datevon.Month, datevon.Year) <= 0;
  130.                 }
  131.             if (!error && myOptions.bo_UseLastDate)
  132.                 {
  133.                 struct myDate datebis;
  134.  
  135.                 UnpackDate(myOptions.bo_LastDate, &datebis);
  136.                 error = fprintf(ProtFileHandle, GetString(MSG_ONLYFILESUPTO_PROT),
  137.                     datebis.Day, datebis.Month, datebis.Year) <= 0;
  138.                 }
  139.             }
  140.         if (!error)
  141.             error = fprintf(ProtFileHandle, GetString(MSG_BACKUPSTARTAT_PROT),
  142.                 StartZeit[3], StartZeit[2], StartZeit[1]+1980,
  143.                 StartZeit[4], StartZeit[5], StartZeit[6] ) <= 0;
  144.  
  145.         /* Anzahl Einträge und Startzeit */
  146.         if (!error)
  147.             {
  148.             fgetpos(ProtFileHandle, &InfoPos);
  149.             error = fprintf(ProtFileHandle, ":INFO %8ld %6ld %6ld\n\n",
  150.                     ProtNfCount,
  151.                     (StartZeit[3]*100 + StartZeit[2])*100 + StartZeit[1],
  152.                     (StartZeit[4]*100 + StartZeit[5])*100 + StartZeit[6] );
  153.             }
  154.  
  155.         if (error)
  156.             error = fprintf(ProtFileHandle, GetString(MSG_PROTHEADER_1)) <= 0;
  157.         if (!error)
  158.             error = fprintf(ProtFileHandle, GetString(MSG_PROTHEADER_2)) <= 0;
  159.  
  160.         }
  161.  
  162.     if (error)
  163.         {
  164.         // Protokoll wird nach Fehler gelöscht
  165.         alarm(GetString(MSG_ERRORWRITING_PROTFILE), myOptions.bo_ProtFileName, GetIoErrText());
  166.         CleanupProtFile(FALSE);
  167.         }
  168. }
  169.  
  170.  
  171. static void TranslateProtFileName(char *ProtFileName, size_t MaxLength)
  172. {
  173.     char Temp[FMSIZE];
  174.     char *p;
  175.  
  176.     stccpy(Temp, ProtFileName, sizeof(Temp));
  177.  
  178.     for (p=Temp; MaxLength && *p;)
  179.         {
  180.         if ('%' == *p)
  181.             {
  182.             p++;
  183.             switch (tolower(*p))
  184.                 {
  185.             case 'd':        /* Datum einfügen */
  186.                 p++;
  187.                 if (MaxLength >= 6)
  188.                     {
  189.                     sprintf(ProtFileName, "%02d%02d%02d",
  190.                         (StartZeit[1]+80) % 100, StartZeit[2], StartZeit[3] );
  191.                     ProtFileName += 6;
  192.                     MaxLength -= 6;
  193.                     }
  194.                 break;
  195.             case 't':        /* Startzeit einfügen */
  196.                 p++;
  197.                 if (MaxLength >= 6)
  198.                     {
  199.                     sprintf(ProtFileName, "%02d%02d%02d",
  200.                         StartZeit[4], StartZeit[5], StartZeit[6]);
  201.                     ProtFileName += 6;
  202.                     MaxLength -= 6;
  203.                     }
  204.                 break;
  205.             default:
  206.                 *ProtFileName++ = '%';
  207.                 MaxLength--;
  208.                 break;
  209.                 }
  210.             }
  211.         else
  212.             {
  213.             *ProtFileName++ = *p++;
  214.             MaxLength--;
  215.             }
  216.         }
  217. }
  218.  
  219.  
  220. static short WriteBinProt(struct NameField *file, FILE *fd)
  221. {
  222.     short error;
  223.     unsigned long Flags;
  224.  
  225.     error = fprintf(fd, " %7ld\n", file->FileLen) < 0;
  226.     if (error)
  227.         return error;
  228.  
  229.     Flags = 0l;
  230.     if (file->isComplete)
  231.         Flags |= 0x80000000;
  232.     if (COMPRESS_NONE != file->CompressionType)
  233.         Flags |= 0x40000000 | file->CompressionType;
  234.  
  235.     error = fprintf(fd, "X %lx %ld %lx %lx %lx %lx %d %d %lx\n",
  236.             file->Offset,
  237.             file->RecordedLen, 
  238.             file->FileDate.ds_Days, file->FileDate.ds_Minute,
  239.             file->FileDate.ds_Tick,
  240.             file->Protection,
  241.             file->Extension, file->SessionNr, Flags
  242.             ) < 0;
  243.     if (error)
  244.         return error;
  245.  
  246.     if (file->NameLen > strlen(file->Name))
  247.         {
  248.         /* Filenote schreiben */
  249.         error = fprintf(fd, "O %s\n", file->Name + strlen(file->Name) + 1) < 0;
  250.         }
  251.  
  252.     return error;
  253. }
  254.  
  255.  
  256. /* Alle Files einer Diskette in das ProtFile eintragen */
  257. void WriteProtFile(struct NameField *file, unsigned char disknr)
  258. {
  259.     size_t len;
  260.     short error = 0;
  261.     char *fname, Kenn='F';
  262.     struct NameField *aktNf;
  263.     short ShortDiskNr = disknr;
  264.     InfoLineHandle Pil;
  265.  
  266.     ASSERT_VALID(file);
  267.  
  268.     SetBusyPointer(aktWindow, TRUE);
  269.     Pil = PushInfoLine(GetString(MSG_WRITING_PROTFILE));
  270.  
  271.     switch (myOptions.bo_ProtFile)
  272.         {
  273.     case PT_Binary:
  274.         while (!error && file)
  275.             {
  276.             ProtNfCount++;
  277.             len = NF_LEN(file);
  278.             ProtNfLength += len + sizeof(short);
  279.  
  280.             error = fwrite(&ShortDiskNr, sizeof(short), 1, ProtFileHandle) != 1
  281.                 || fwrite(file, len, 1, ProtFileHandle) != 1;
  282.  
  283.             file = file->NextName;
  284.             }
  285.         break;
  286.  
  287.     case PT_ASCII:
  288.         /* Einträge zählen und in den Kopf des Protokollfiles eintragen */
  289.         for (aktNf=file; aktNf; aktNf=aktNf->NextName)
  290.             ProtNfCount++;
  291.  
  292.         while (!error && file)
  293.             {
  294.             ProtNfLength += NF_LEN(file);
  295.  
  296.             len = strlen(file->Name) + 2;
  297.             fname = file->Name;
  298.             while (!error && len)
  299.                 {
  300.                 if (Kenn != 'C' && (file->isSoftLink))
  301.                     Kenn = 'L';
  302.                 if (Kenn != 'C' && (file->isHardLink))
  303.                     Kenn = 'H';
  304.                 if (Kenn != 'C' && (file->isDir))
  305.                     Kenn = 'E';
  306.                 if (Kenn != 'C' && (file->isPartition))
  307.                     Kenn = 'P';
  308.  
  309.                 if (len <= PROT_FNAME_LEN)
  310.                     {
  311.                     /* Name paßt in eine Zeile */
  312.                     error = fprintf(ProtFileHandle, "%c %-3d \"%s\"%*s",
  313.                             file->Extension ? tolower(Kenn) : Kenn,
  314.                             disknr, fname,
  315.                             PROT_FNAME_LEN-len, "") < 0;
  316.  
  317.                     if (Kenn != 'C')
  318.                         error = error || WriteBinProt(file, ProtFileHandle);
  319.                     else
  320.                         error = fprintf(ProtFileHandle, "\n") < 0;
  321.  
  322.                     len = 0;
  323.                     Kenn = 'F';
  324.                     }
  325.                 else
  326.                     {
  327.                     /* Verlängerungszeile für Filenamen */
  328.                     error = fprintf(ProtFileHandle, "%c %-3d \"%*.*s»",
  329.                             file->Extension ? tolower(Kenn) : Kenn,
  330.                             disknr,
  331.                             PROT_FNAME_LEN-2, PROT_FNAME_LEN-2,
  332.                             fname) < 0;
  333.  
  334.                     if (Kenn != 'C')
  335.                         error = error || WriteBinProt(file, ProtFileHandle);
  336.                     else
  337.                         error = fprintf(ProtFileHandle, "\n") < 0;
  338.  
  339.                     Kenn = 'C';
  340.                     fname += PROT_FNAME_LEN-2;
  341.                     len -= PROT_FNAME_LEN-2;
  342.                     }
  343.                 }
  344.             file = file->NextName;
  345.             }
  346.         break;
  347.         }
  348.  
  349.     SetBusyPointer(aktWindow, FALSE);
  350.     PopInfoLine(&Pil);
  351.  
  352.     if (error)
  353.         {
  354.         // Protokoll wird nach Fehler gelöscht
  355.         alarm(GetString(MSG_ERRORWRITING_PROTFILE), myOptions.bo_ProtFileName, GetIoErrText());
  356.         CleanupProtFile(FALSE);
  357.         }
  358. }
  359.  
  360.  
  361. void CleanupProtFile(BOOL KeepProtFile)
  362. {
  363.     if (ProtFileHandle)
  364.         {
  365.         switch (myOptions.bo_ProtFile)
  366.             {
  367.         case PT_Binary:
  368.             {
  369.             struct DiskLabel ProtLabel;
  370.  
  371.             BuildDiskLabel(&ProtLabel, disknr);
  372.  
  373.             ProtLabel.DirAnz = ProtNfCount;
  374.             ProtLabel.DirLen = ProtNfLength;
  375.  
  376.             // Label-Prüfsumme korrigieren!
  377.             ProtLabel.LabelCheckSum = 0l;
  378.             ProtLabel.LabelCheckSum = -ComputeLabelCheckSum(&ProtLabel);
  379.  
  380.             fwrite(&ProtLabel, sizeof(ProtLabel), 1, ProtFileHandle);
  381.             }
  382.             break;
  383.  
  384.         case PT_ASCII:
  385.             if (InfoPos)
  386.                 {
  387.                 /* endgültige Anzahl Einträge und Startzeit eintragen */
  388.                 if (fsetpos(ProtFileHandle, &InfoPos) == 0)
  389.                     {
  390.                     fprintf(ProtFileHandle, ":INFO %8ld %6ld %6ld\n\n",
  391.                         ProtNfCount,
  392.                         (StartZeit[3]*100 + StartZeit[2])*100 + StartZeit[1],
  393.                         (StartZeit[4]*100 + StartZeit[5])*100 + StartZeit[6] );
  394.                     }
  395.                 }
  396.             InfoPos = 0;
  397.             break;
  398.             }
  399.  
  400.         fclose(ProtFileHandle);
  401.         ProtFileHandle = NULL;
  402.         }
  403.  
  404.     if (!KeepProtFile && !ProtFileValid)
  405.         {
  406.         // wenn nicht wenigstens einmal NamenSchreiben erfolgreich beendet wurde, dann
  407.         // steht nur Schrott im ProtFile.. Also wird es dann gelöscht!
  408.         DeleteFile(myOptions.bo_ProtFileName);
  409.         }
  410. }
  411.  
  412.  
  413. void CompressProtocol(void)
  414. {
  415.     if (PT_Binary == myOptions.bo_ProtFile && myOptions.bo_KeepProtFile)
  416.         {
  417.         // binäre nicht-temporäre Protfiles werden automatisch komprimiert
  418.         CompressProtFile(myOptions.bo_ProtFileName);
  419.         }
  420. }
  421.  
  422.  
  423. BOOL isProtFile(const char *Path, const char *FileName)
  424. {
  425.     char FilePath[FMSIZE];
  426.  
  427.     if (NULL == ProtFileHandle)
  428.         return FALSE;
  429.  
  430.     stccpy(FilePath, Path,  sizeof(FilePath));
  431.     if (!AddPart(FilePath, (STRPTR) FileName, sizeof(FilePath)))
  432.         return FALSE;
  433.  
  434.     return (BOOL) (stricmp(FilePath, NormalizedProtFileName) == 0);
  435. }
  436.  
  437.  
  438. static BOOL CompressProtFile(const char *ProtFileName)
  439. {
  440.     char *TempName;
  441.     BOOL Result = FALSE;
  442.     struct NameField *ProtNF = NULL;
  443.     InfoLineHandle Pil;
  444.  
  445.     SetBusyPointer(aktWindow, TRUE);
  446.     Pil = PushInfoLine(GetString(MSG_COMPRESSING_PROTFILE));
  447.  
  448.     while (1)
  449.         {
  450.         char ProtFilePath[FMSIZE];
  451.         static struct FileInfoBlock __aligned fib;
  452.  
  453.         if (!InitCompress())
  454.             break;
  455.  
  456.         stcgfp(ProtFilePath, ProtFileName);
  457.         AddPart(ProtFilePath, (STRPTR) "Prot", sizeof(ProtFilePath));
  458.  
  459.         TempName = tempname(ProtFilePath);
  460.         if (NULL == TempName)
  461.             break;
  462.  
  463.         aktReadFileHandle = Open((STRPTR) ProtFileName, MODE_OLDFILE);
  464.         if (NULL == aktReadFileHandle)
  465.             break;
  466.  
  467.         if (!ExamineFH(aktReadFileHandle, &fib))
  468.             break;
  469.  
  470.         ProtNF = calloc(sizeof(struct NameField) + strlen(ProtFileName), 1);
  471.         if (NULL == ProtNF)
  472.             break;
  473.  
  474.         FillNameField(ProtNF, &fib);
  475.         strcpy(ProtNF->Name, ProtFileName);
  476.  
  477.         if (!Rename((STRPTR) ProtFileName, FilePart((STRPTR) TempName)))
  478.             break;
  479.  
  480.         CompressedProtFileHandle = Open((STRPTR) ProtFileName, MODE_NEWFILE);
  481.         if (NULL == CompressedProtFileHandle)
  482.             break;
  483.  
  484.         // Header für komprimiertes ProtFile schreiben
  485.         Write(CompressedProtFileHandle, (STRPTR) COMPRESSEDPROTFILEHEADER,
  486.             sizeof(COMPRESSEDPROTFILEHEADER));
  487.  
  488.         // Länge des unkomprimierten Files hier merken!
  489.         Write(CompressedProtFileHandle, &fib.fib_Size,
  490.             sizeof(fib.fib_Size));
  491.  
  492.         // PROTFILEHEADER überlesen
  493.         Seek(aktReadFileHandle, sizeof(PROTFILEHEADER), OFFSET_BEGINNING);
  494.         ProtNF->FileLen -= sizeof(PROTFILEHEADER);
  495.  
  496.         CompressFile(ProtNF, ProtNF->FileLen, WriteCompressedProt);
  497.         Close(aktReadFileHandle);
  498.         aktReadFileHandle = NULL;
  499.         Result = TRUE;
  500.         break;
  501.         }
  502.  
  503.     if (CompressedProtFileHandle)
  504.         {
  505.         Close(CompressedProtFileHandle);
  506.         CompressedProtFileHandle = NULL;
  507.         }
  508.     if (TempName)
  509.         {
  510.         if (Result)
  511.             DeleteFile(TempName);        // altes (unkomprimiertes) ProtFile löschen
  512.         else
  513.             Rename(TempName, FilePart((STRPTR) ProtFileName));    // Originales ProtFile wiederherstellen
  514.  
  515.         free(TempName);
  516.         }
  517.     if (ProtNF)
  518.         free(ProtNF);
  519.  
  520.     SetBusyPointer(aktWindow, FALSE);
  521.     PopInfoLine(&Pil);
  522.  
  523.     return Result;
  524. }
  525.  
  526.  
  527. static void WriteCompressedProt(struct NameField **nf, char *Bytes, size_t Length)
  528. {
  529.     if (CompressedProtFileHandle)
  530.         Write(CompressedProtFileHandle, Bytes, Length);
  531. }
  532.